package com.hcycom.hcymybatis.mapper;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hcycom.hcymybatis.utils.CollectionsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
import java.lang.reflect.Field;
import java.util.List;

public class BaseServiceImplement< T extends BasicEntity> implements BasicService<T> {

    @Autowired(required = true)
    protected MyMapper<T> mapper;

    /**
     * 根据实体类中的属性值查询，条件之间使用=号  返回第一条数据
     * @param record
     * @return
     */
    @Override
    public T selectOne(T record) {
        List<T> data=mapper.select(record);
        if (!CollectionsUtil.isEmpty(data) && data.size() > 0) {
            return data.get(0);
        }
        return null;
    }

    /**
     * 根据实体类不为null的字段进行查询,条件全部使用=号and条件
     *
     * @param < T
	 *            extend T>
     */
    public List<T> select(T record) {
        // record.set("delFlag", Constant.DEL_FLAG_NORMAL);
        return mapper.select(record);
    }

    /**
     * 根据实体类不为null的字段进行查询,条件全部使用=号and条件
     * @param record orderSqlStr 排序方式
     * @return
     */
    public List<T> select(T record, String orderSqlStr) {
        Example example = new Example(record.getClass(), false);
        Criteria criteria = null;
        try {
            Field[] declaredFields = record.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                if (field.get(record) != null && !"".equals(field.get(record))) {
                    if(criteria==null) {
                        criteria=example.createCriteria();
                    }
                    criteria.andEqualTo(field.getName(), field.get(record));
                }
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (orderSqlStr != null || !"".equals(orderSqlStr)) {
            example.setOrderByClause(orderSqlStr);
        }
        return mapper.selectByExample(example);
    }

    /**
     * 根据实体类不为null的字段查询总数,条件全部使用=号and条件
     *
     * @param < T
	 *            extend T>
     */
    public int selectCount(T record) {
        // record.set("delFlag", Constant.DEL_FLAG_NORMAL);
        return mapper.selectCount(record);
    }

    /**
     * 根据主键进行查询,必须保证结果唯一 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
     *
     * @param < T
	 *            extend T>
     */
    public T selectByPrimaryKey(Object key) {
        return mapper.selectByPrimaryKey(key);
    }

    /**
     * 插入一条数据,只插入不为null的字段,不会影响有默认值的字段 支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写)
     * 优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长
     *
     * @param < T
	 *            extend T>
     */
    public int insertSelective(T record) {
        return mapper.insertSelective(record);
    }

    /**
     * 根据实体类不为null的字段进行查询,条件全部使用=号and条件
     *
     * @param < T
	 *            extend T>
     */
    public int delete(T key) {
        return mapper.delete(key);
    }

    /**
     * 通过主键进行删除,这里最多只会删除一条数据 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
     *
     * @param < T
	 *            extend T>
     */
    public int deleteByPrimaryKey(Object key) {
        return mapper.deleteByPrimaryKey(key);
    }

    /**
     * 根据主键进行更新 只会更新不是null的数据
     *
     * @param < T
	 *            extend T>
     */
    public int updateByPrimaryKeySelective(T record) {

        return mapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 根据主键进行更新 null会被更新
     *
     * @param < T
	 *            extend T>
     */
    public int updateByPrimaryKey(T record) {
        return mapper.updateByPrimaryKey(record);
    }

    /**
     * 单表分页
     *
     * @param pageNum
     *            页码
     * @param pageSize
     *            条数
     * @param record
     *            条件实体
     * @return
     */
    public PageInfo<T> selectPage(int pageNum, int pageSize, T record) {
        // record.set("delFlag", Constant.DEL_FLAG_NORMAL);
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<T>(mapper.select(record));
    }

    /**
     * @Description:(单表分页可排序)
     * @param:@param pageNum
     * @param:@param pageSize
     * @param:@param record
     * @param:@param orderSqlStr
     *                   (如:id desc)
     * @return:PageInfo<T>
     */
    public PageInfo<T> selectPage(int pageNum, int pageSize, T record, String orderSqlStr) {
        Example example = new Example(record.getClass(), false);
        // Criteria criteria = example.createCriteria();
        // criteria.andEqualTo("delFlag", Constant.DEL_FLAG_NORMAL);
        // for(Map.Entry<String, Object> entry : ((Map) record).entrySet()){
        // if("".equals(entry.getValue())) continue;
        // criteria.andEqualTo(entry.getKey(), entry.getValue());
        // }
        // example.orderBy("id").desc().orderBy("countryname").orderBy("countrycode").asc();
        // List<Country> countries = mapper.selectByExample(example);
        example.setOrderByClause(orderSqlStr);
        PageHelper.startPage(pageNum, pageSize);
        List<T> list = mapper.selectByExample(example);
        return new PageInfo<T>(list);
    }

    @Override
    public int insertList(List<T> list) {
        return mapper.insertLists(list);
    }

    /**
     * 保存或者更新，根据传入id主键是不是null来确认
     *
     * @param record
     * @return 影响行数
     */
    @Override
    public int insertOrUpdate(T record) {
        int count = 0;
        if (record.getId() == null) {
            count = this.insertSelective(record);
        } else {
            count = this.updateByPrimaryKeySelective(record);
        }
        return count;
    }

    @Override
    public PageInfo<T> selectPages(int pageNum, int pageSize, T record, String orderStr) {
        Example example = new Example(record.getClass(), false);
        Criteria criteria = null;
        try {
            Field[] declaredFields = record.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                if (field.get(record) != null && !"".equals(field.get(record))) {
                    if(criteria==null) {
                        criteria=example.createCriteria();
                        criteria.andCondition("1=1");
                    }
                    criteria.andEqualTo(field.getName(), field.get(record));
                }
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (orderStr != null || !"".equals(orderStr)) {
            example.setOrderByClause(orderStr);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<T> list = mapper.selectByExample(example);
        return new PageInfo<T>(list);
    }

}
